//================================================================================================================================
// Routines to interpret the data sent from TCPIPController   
//================================================================================================================================
                        
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "MCE.h"
#include "MCE_Mode.h"


//================================================================================================================================
// Routine to decode the current line into a global
//================================================================================================================================
void MCE_interpret( char *line)
{
     int tag;
     int wasi;          // previous value of Integer type tag
     char wass[256];    // previous value of String type tag
     char str[80];
     
     // Interpret the line and store the resulting value
     // Search the table of tags for the one from Media Center
     // Once found store the associated value in the tag table against this tag
     tag=puttag(line,wass,&wasi);
     if (tag<NUM_MTAGS)
         {
              sprintf(str,"tag=%d,wasi=%d,wass=%s",tag,wasi,wass);
              Tlog("Interpret processing tag ",str);
              // Tag dependant stuff now
              switch (tag)
              {
                 case TAG_TrackTime:  // Check if TrackTime and if so the set TrackTimeLeft
                          puttime(TAG_TrackTimeLeft,geti(TAG_TrackDuration)-geti(TAG_TrackTime));
                          break;             
                         
                 case TAG_StartSession:   // set the startsession flag to the session number
                          puti(TAG_PreviousStatusFlag,wasi);
                          puti(TAG_SessionFlag,geti(tag));
                          break;

                 case TAG_CD:             // check for session type messages
                 case TAG_DVD:
                 case TAG_TVTuner:
                 case TAG_PVR:
                 case TAG_Photos:
                 case TAG_Radio:
                          putst(TAG_NextSessionType,getdisplay(tag)); putst(TAG_SessionType," ");
                 case TAG_StreamingContentAudio:
                 case TAG_StreamingContentVideo:
//                          putst(TAG_NextSessionType,"Radio"); putst(TAG_SessionType," ");
//                          putst(TAG_NextSessionType,getdisplay(tag)); putst(TAG_SessionType," ");
                          puti(TAG_Status,tag);              // update the status if its a menu operation
                          putst(TAG_Status,getdisplay(tag));
                          break;
                 case TAG_FS_Home:
                 case TAG_FS_DVD:
                 case TAG_FS_Extensibility:
                 case TAG_FS_Guide:
                 case TAG_FS_Music:
                 case TAG_FS_Photos:
                 case TAG_FS_Radio:
                 case TAG_FS_RecordedShows:
                 case TAG_FS_TV:
                 case TAG_FS_Unknown:
                 case TAG_FS_Videos:
                          putbi(TAG_FS_Home,0);    putbi(TAG_FS_DVD,0);   putbi(TAG_FS_Extensibility,0);
                          putbi(TAG_FS_Guide,0);   putbi(TAG_FS_Music,0); putbi(TAG_FS_Photos,0);
                          putbi(TAG_FS_Radio,0);   putbi(TAG_FS_TV,0);    putbi(TAG_FS_RecordedShows,0);
                          putbi(TAG_FS_Unknown,0); putbi(TAG_FS_Videos,0);
                          putbi(tag,1);
                          puti(TAG_NavStatus,tag); putst(TAG_NavStatus,getdisplay(tag));
                          puti(TAG_Status,tag);              // update the status if its a menu operation
                          putst(TAG_Status,getdisplay(tag));
                          break;
                 case TAG_Play:
                          if (geti(TAG_Initialising)==0) set_mode(tag,1,0,0,0,0,0,0,0,0,0,0,0);  // Play
                          break;
                 case TAG_Stop:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,1,0,0,0,0,0,0,0,0,0,0);  // Stop
                          break;
                 case TAG_Pause:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,1,0,0,0,0,0,0,0,0,0);  // Pause
                          break;
                 case TAG_FF1:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,1,0,0,0,0,0,0,0,0);  // FF1
                          break;
                 case TAG_FF2:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,1,0,0,0,0,0,0,0);  // FF2
                          break;
                 case TAG_FF3:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,0,1,0,0,0,0,0,0);  // FF3
                          break;
                 case TAG_Rewind1:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,0,0,1,0,0,0,0,0);  // Rewind1
                          break;
                 case TAG_Rewind2:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,0,0,0,1,0,0,0,0);  // Rewind2
                          break;
                 case TAG_Rewind3:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,0,0,0,0,1,0,0,0);  // Rewind3
                          break;
                 case TAG_SlowMotion1:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,0,0,0,0,0,1,0,0);  // Rewind1
                          break;
                 case TAG_SlowMotion2:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,0,0,0,0,0,0,1,0);  // Rewind2
                          break;
                 case TAG_SlowMotion3:
                          if (geti(TAG_Initialising)==0) set_mode(tag,0,0,0,0,0,0,0,0,0,0,0,1);  // Rewind3
                          break;
                 case TAG_Mute:
                 case TAG_Next:
                 case TAG_NextFrame:
                 case TAG_PhoneCall:
                 case TAG_Prev:
                 case TAG_PrevFrame:
                 case TAG_Volume:
                          if (geti(TAG_Initialising)==0) { start_counter(tag); } // Mute etc. temporary displays
                          break;         
                case TAG_DiscWriter_Start:
                          puti(TAG_StartSession,geti(TAG_PreviousStatusFlag));
                          puti(TAG_SessionFlag,geti(TAG_PreviousStatusFlag));
                          putbi(TAG_DiscWriter_Stop,0);
                          break;
                case TAG_DiscWriter_Stop:
                          putbi(TAG_DiscWriter_Start,0);
                          break;
                case TAG_Recording:
                          if (geti(TAG_IgnoreSpuriousRecording)!=0) { if (geti(TAG_Initialising)!=0) break; }
                          MCE_update_recording_status(tag,wasi,wass,line);
                          break;
                case TAG_MediaName:
                          MCE_update_recording_status(tag,wasi,wass,line);
                          break;
                case TAG_RadioFrequency:                          
                          if (!strcmp(getst(TAG_RadioChannelTag),gettag(TAG_RadioFrequency)))
                                 putst(TAG_RadioChannel,MCE_dll_get_radiochannel(&line[getlength(tag)+1]));
                          break;
                case TAG_TrackNumber:    // Check if Tracknumber and we are in TV mode - if so set the TV Channel Name
                          MCE_update_recording_status(tag,wasi,wass,line);
                          break;
                case TAG_EndSession:
                          MCE_update_recording_status(tag,wasi,wass,line);
//                          if (geti(TAG_Initialising)==0) set_mode(TAG_Stop,0,1,0,0,0,0,0,0,0,0,0,0);  // Stop implied
                          break;
               }   // end of switch statement
               
               // if we are in a session then if this is a session type message store it
               if (geti(TAG_SessionFlag)!=0)
                 { if ( (tag==TAG_CD) || (tag==TAG_StreamingContentAudio) || (tag==TAG_StreamingContentVideo) ||
                        (tag==TAG_TVTuner) || (tag==TAG_PVR)  || (tag==TAG_Photos) || (tag==TAG_Radio) ||
                        (tag==TAG_DVD) )
                     { putst(TAG_SessionStatus,getdisplay(tag)); puti(TAG_SessionValue,tag); }
                   // we are in a session - is this an endsession?
                   if (tag==TAG_EndSession)
                     { if (geti(TAG_SessionFlag)==geti(tag)) // is it the end of the current session?
                         { sprintf(str,"Session ended status=%s, value=%d, Flag=%d, session=%d",
                                  getst(TAG_SessionStatus),geti(TAG_SessionValue),geti(TAG_SessionFlag),geti(tag));
                           Tlog("Interpret",str);
                           puti(TAG_SessionFlag,0);             // it is so set not waiting on a session
                           puti(TAG_SessionValue,0);
                           putst(TAG_SessionStatus,getdisplay(TAG_Menu)); // Default the status
                         }
                        // what if it's the end of another session?
                     }
                  }
        }
}   



//================================================================================================================================
// Routine to get the next line from the current message - there can be more than 1 line in each
//================================================================================================================================
int MCE_extract_line(char msgbuf[], int ptr, char line[])
{
    int i,j;
    //printf("extract_line %u\nmsgbuf=%s\n",ptr,msgbuf);
    i=ptr; j=0;
    if (msgbuf[i]=='\n') i++;
    if (msgbuf[i]!='\0' && msgbuf[i]!='\r')
      { do { line[j++]=msgbuf[i++]; } while (msgbuf[i]!='\0' && msgbuf[i]!='\r' && msgbuf[i]!='\n'); }
    line[j]=0;
    return i-ptr;
}




//================================================================================================================================
// Routine to extract the tags from the current message and interpret them
//================================================================================================================================
void MCE_decode( char *msgbuf)
{
     int ptr,linelen;
     char line[512];
     
     ptr=0;
     puti(TAG_Initialising,0); 
     //printf("message is: %u %s\n",ptr,msgbuf); 
     //Tlog("decode new message",msgbuf);
     linelen=MCE_extract_line(msgbuf,ptr,line);
     // Check if this is the initial message
     if (!strncmp(line,"204",3)) { puti(TAG_Initialising,1); Tlog("Initialising","1"); }
     
     while (linelen>0 && line[0]!='\0' && line[0]!='\r' && line[0]!='\n')
     { Tlog("decode",line);
       if (strncmp(line,"204",3)) MCE_interpret(line); // interpret it if it's not a 204 line
       //printf("Line (%u)=%s\n",linelen,line); 
       ptr=ptr+linelen+1;
       linelen=MCE_extract_line(msgbuf,ptr,line);
     }
     puti(TAG_Initialising,0); 
}

